import React, {useEffect, useState} from 'react';
import {observer} from 'mobx-react';
import {Navigation, NavigationFunctionComponent} from 'react-native-navigation';
import {
  useNavigationComponentDidAppear,
  useNavigationComponentDidDisappear,
} from 'react-native-navigation-hooks';
import {Lrc} from '@rojer/react-native-lrc';
import {ImageBackground, View} from 'react-native';
import Slider from '@react-native-community/slider';
import styled from 'styled-components/native';
import debounce from 'lodash.debounce';
import TrackPlayer, {State} from 'react-native-track-player';
import {useKeepAwake} from '@unsw-gsbme/react-native-keep-awake';
import {Poster, Flex, Button, Text, Focusable, Container} from '../components';
import {useGlobal, usePlayer} from '../hooks/useStores';
import useWidth from '../hooks/useWidth';
import usePlaybackState from '../hooks/usePlaybackState';
import {useRef} from 'react';

const LrcBox = styled.View<{height: number; width: number}>`
  height: ${props => `${props.height}px`};
  width: 100%;
`;

const ControlerBox = styled(Flex)`
  height: 100px;
  width: 100%;
  padding-bottom: 20px;
`;

const Icon = styled.Image<{size?: number}>`
  height: ${props => (props.size ? `${props.size}px` : '23px')};
  width: ${props => (props.size ? `${props.size}px` : '23px')};
`;
interface Props {}

const loops: any = {
  list: require('../assets/icon_loop_list.png'),
  random: require('../assets/icon_loop_random.png'),
  signal: require('../assets/icon_loop_signal.png'),
};

const Music: NavigationFunctionComponent<Props> = observer(({componentId}) => {
  const {
    mode,
    current,
    lyric,
    loop_mode,
    setLoop,
    fmTrash,
    skipToNext,
    skipToPrevious,
  } = usePlayer();

  const visiable = useRef<boolean>(false);
  const {likelist, likeMusic} = useGlobal();
  const slideing = React.useRef<boolean>(false);
  const {height, w1, w5, w3} = useWidth();
  const [liked, setLiked] = React.useState(false);

  useNavigationComponentDidAppear(() => {
    visiable.current = true;
  }, componentId);

  useNavigationComponentDidDisappear(() => {
    visiable.current = false;
  }, componentId);

  useKeepAwake();

  React.useEffect(() => {
    Navigation.mergeOptions(componentId, {
      topBar: {
        title: {
          text: current?.name,
        },
      },
    });
    setLiked(likelist.includes(current?.id));
  }, [current, likelist, setLiked, componentId]);

  const lineRenderer = React.useCallback(
    ({lrcLine: {content}, active}) => (
      <Text
        color={active ? 'rgba(255,255,255,1)' : 'rgba(255,255,255,0.7)'}
        size={active ? 28 : 18}
        numberOfLines={1}
        style={{textAlign: 'center'}}>
        {content}
      </Text>
    ),
    [],
  );

  const toggleLoop = () => {
    const next: any = {
      list: 'random',
      random: 'signal',
      signal: 'list',
    };
    setLoop(next[loop_mode]);
  };

  const [processState, setProcessState] = useState({position: 0, duration: 0});
  const playerState = usePlaybackState();

  useEffect(() => {
    let unmount = false;

    if (playerState === State.Stopped) {
      setProcessState({position: 0, duration: 0});
      return;
    }

    if (playerState === State.Buffering) {
      return;
    }

    const poll = setInterval(async () => {
      const [position, duration] = await Promise.all([
        TrackPlayer.getPosition(),
        TrackPlayer.getDuration(),
      ]);
      if (
        !unmount &&
        playerState === State.Playing &&
        visiable.current && // 可见
        !slideing.current // 非滑动中
      ) {
        setProcessState({position, duration});
      }
    }, 1000);

    return () => {
      clearInterval(poll);
      unmount = true;
    };
  }, [playerState]);

  const {position, duration} = processState;

  const slideTime = debounce((time: number) => {
    TrackPlayer.seekTo(time);
    slideing.current = false;
  }, 1000);

  return (
    <View
      style={{
        height: '100%',
        width: '100%',
        position: 'relative',
      }}>
      {current?.poster ? (
        <ImageBackground
          source={{uri: `${current?.poster}?param=${w5}y${w5}`}}
          blurRadius={18}
          style={{
            height: '100%',
            width: '100%',
            opacity: 0.5,
            position: 'absolute',
            zIndex: 1,
          }}
        />
      ) : null}

      <Flex
        direction="column"
        style={{
          height: '100%',
          width: '100%',
          position: 'relative',
          zIndex: 998,
        }}>
        <Flex style={{flex: 1}} align="center" justify="center">
          <Poster />
          <View style={{marginLeft: 24, width: w3 * 2}}>
            <Flex
              style={{marginBottom: 12}}
              direction="column"
              justify="center"
              align="center">
              <Text
                size={36}
                numberOfLines={1}
                style={{textAlign: 'center', width: '100%', marginBottom: 12}}>
                {current?.name}
              </Text>

              <Flex justify="center" align="center">
                <Text color="rgba(255,255,255, 0.4)" style={{marginRight: 10}}>
                  专辑：{current?.genre}
                </Text>

                <Text color="rgba(255,255,255, 0.4)" style={{marginLeft: 10}}>
                  歌手：{current?.artists}
                </Text>
              </Flex>
            </Flex>

            <LrcBox height={height * 0.5} width={w3 * 2}>
              <Lrc
                height={height * 0.5}
                lrc={lyric || ''}
                currentTime={position * 1000}
                lineHeight={38}
                activeLineHeight={58}
                lineRenderer={lineRenderer}
                scrollEnabled={false}
              />
            </LrcBox>
          </View>
        </Flex>

        <Container>
          <Slider
            style={{width: w1, height: 40}}
            minimumValue={0}
            maximumValue={duration}
            thumbTintColor="#FFFFFF"
            minimumTrackTintColor="#FFFFFF"
            maximumTrackTintColor="#FFFFFF"
            value={position}
            onValueChange={time => {
              slideing.current = true;
              slideTime(time);
            }}
          />
        </Container>

        <ControlerBox justify="center" align="center" direction="column">
          <Flex align="center">
            {/* 循环模式 */}
            {mode !== 'fm' ? (
              <Focusable
                shadow={false}
                radius={40}
                onPress={toggleLoop}
                style={{marginRight: 24}}>
                <Button height={40} width={40} radius={40}>
                  <Icon source={loops[loop_mode]} resizeMode="contain" />
                </Button>
              </Focusable>
            ) : null}

            {/* 不喜欢 */}
            {mode === 'fm' ? (
              <Focusable
                shadow={false}
                radius={40}
                onPress={async () => {
                  await fmTrash(current?.id);
                }}
                style={{marginRight: 24}}>
                <Button height={40} width={40} radius={40}>
                  <Icon
                    source={require('../assets/icon_dislike.png')}
                    resizeMode="contain"
                  />
                </Button>
              </Focusable>
            ) : null}

            {/* 上一首 */}
            {mode !== 'fm' ? (
              <Focusable
                shadow={false}
                radius={40}
                onPress={async () => {
                  skipToPrevious();
                }}
                style={{marginRight: 24}}>
                <Button height={40} width={40} radius={40}>
                  <Icon
                    source={require('../assets/icon_pre.png')}
                    resizeMode="contain"
                  />
                </Button>
              </Focusable>
            ) : null}

            {mode === 'fm' ? (
              <View style={{marginRight: 24, borderRadius: 40, opacity: 0.4}}>
                <Button height={40} width={40} radius={40}>
                  <Icon
                    source={require('../assets/icon_pre.png')}
                    resizeMode="contain"
                  />
                </Button>
              </View>
            ) : null}

            {/* 播放 / 暂停 */}
            <Focusable
              shadow={false}
              radius={50}
              onPress={() => {
                if (playerState === State.Playing) {
                  TrackPlayer.pause();
                }
                if (playerState === State.Paused) {
                  TrackPlayer.play();
                }
              }}>
              <Button height={50} width={50} radius={50}>
                <Icon
                  source={
                    playerState === State.Playing
                      ? require('../assets/icon_pause.png')
                      : require('../assets/icon_play.png')
                  }
                  resizeMode="contain"
                />
              </Button>
            </Focusable>

            {/* 下一首 */}
            <Focusable
              shadow={false}
              radius={40}
              onPress={async () => {
                skipToNext();
              }}
              style={{marginLeft: 24}}>
              <Button height={40} width={40} radius={40}>
                <Icon
                  source={require('../assets/icon_next.png')}
                  resizeMode="contain"
                />
              </Button>
            </Focusable>

            {/* 喜欢 */}
            <Focusable
              shadow={false}
              radius={40}
              onPress={() => {
                likeMusic(current?.id, !liked);
              }}
              style={{marginLeft: 24}}>
              <Button height={40} width={40} radius={40}>
                <Icon
                  source={
                    liked
                      ? require('../assets/icon_liked.png')
                      : require('../assets/icon_like.png')
                  }
                  resizeMode="contain"
                />
              </Button>
            </Focusable>
          </Flex>
        </ControlerBox>
      </Flex>

      <Focusable
        shadow={false}
        onPress={() => {
          Navigation.pop(componentId);
        }}
        radius={40}
        width={0}
        style={{
          position: 'absolute',
          opacity: 0.5,
          width: 40,
          height: 40,
          left: 30,
          top: 30,
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          marginRight: 'auto',
        }}>
        <Icon
          source={require('../assets/icon_hide.png')}
          resizeMode="contain"
          size={34}
        />
      </Focusable>
    </View>
  );
});

Music.options = {
  topBar: {
    visible: false,
  },
};

export default Music;
